Attribute VB_Name = "WindowUtil"
Option Explicit

Private Type POINTAPI
        x As Long
        y As Long
End Type

Private Type MINMAXINFO
        ptReserved As POINTAPI
        ptMaxSize As POINTAPI
        ptMaxPosition As POINTAPI
        ptMinTrackSize As POINTAPI
        ptMaxTrackSize As POINTAPI
End Type


Private Declare Function ClientToScreen Lib "USER32" (ByVal hWnd As Long, lpPoint As POINTAPI) As Long
Private Declare Function ScreenToClient Lib "USER32" (ByVal hWnd As Long, lpPoint As POINTAPI) As Long
Private Declare Function CallWindowProc Lib "USER32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function SetWindowLong Lib "USER32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSource As Any, ByVal ByteLen As Long)

Private Const GWL_WNDPROC = (-4)
Private Const WM_GETMINMAXINFO = &H24

Dim mOldWindowSizeProc As Long
Dim mhWnd As Long

Dim mMaxWidth As Long
Dim mMinWidth As Long
Dim mMaxHeight As Long
Dim mMinHeight As Long

Private Function WindowSizeProc(ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    If wMsg = WM_GETMINMAXINFO Then
        Dim mmif As MINMAXINFO
        CopyMemory mmif, ByVal lParam, Len(mmif)
        With mmif
            .ptMaxTrackSize.x = mMaxWidth
            .ptMaxTrackSize.y = mMaxHeight
            .ptMinTrackSize.x = mMinWidth
            .ptMinTrackSize.y = mMinHeight
        End With
        CopyMemory ByVal lParam, mmif, Len(mmif)
        WindowSizeProc = 1
        Exit Function
    End If
    WindowSizeProc = CallWindowProc(mOldWindowSizeProc, hWnd, wMsg, wParam, lParam)
End Function

Public Sub HookWindowSize(ByVal hWnd As Long, MinWidth As Long, MinHeight As Long)
    If mOldWindowSizeProc <> 0 Then Exit Sub
    mMaxWidth = Screen.Width / Screen.TwipsPerPixelX
    mMaxHeight = Screen.Height / Screen.TwipsPerPixelY
    mMinWidth = MinWidth
    mMinHeight = MinHeight
    
    mhWnd = hWnd
    mOldWindowSizeProc = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WindowSizeProc)
End Sub

Public Sub UnHookWindowSize(ByVal hWnd As Long)
    If mOldWindowSizeProc = 0 Then Exit Sub
    SetWindowLong hWnd, GWL_WNDPROC, mOldWindowSizeProc
    mOldWindowSizeProc = 0
End Sub



